package org.waigua.moka.processor;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.httpclient.HttpException;
import org.apache.log4j.Logger;
import org.waigua.moka.dto.ApiDto;
import org.waigua.moka.exception.MazeClearException;
import org.waigua.moka.exception.NoFreeResetMazeException;
import org.waigua.moka.exception.SysException;
import org.waigua.moka.service.HttpApiService;
import org.waigua.moka.service.impl.HttpApiServiceImpl;
import org.waigua.moka.util.BigDecimalUtil;

public class MazeProcessor
{
	protected Logger log = Logger.getLogger(getClass());
	HttpApiService httpApiService = new HttpApiServiceImpl();

	public boolean resetMazeIfPossible(int stageId) throws SysException
	{
		try
		{
			Map<String, String> params = new HashMap<String, String>();
			params.put("MapStageId", String.valueOf(stageId));
			ApiDto apiDto = ApiDto.buildPostContentApiDto(params);
			Map<String, ?> showMazeResult = httpApiService.showMaze(apiDto);
			if (BigDecimal.ZERO.compareTo(BigDecimalUtil.convert(showMazeResult.get("FreeReset"))) != 0)
			{
				return resetMaze(stageId);
			}
			throw new NoFreeResetMazeException();
		}
		catch (HttpException e)
		{
			throw new SysException(e);
		}
		catch (IOException e)
		{
			throw new SysException(e);
		}
	}

	private boolean resetMaze(int stageId) throws HttpException, IOException
	{
		Map<String, String> params = new HashMap<String, String>();
		params.put("MapStageId", String.valueOf(stageId));
		ApiDto apiDto = ApiDto.buildPostContentApiDto(params);
		Map<String, ?> resetResult = httpApiService.resetMaze(apiDto);
		System.out.println(resetResult);
		return false;
	}

	public void clearMaze(int stageId) throws SysException
	{
		try
		{
			Map<String, String> params = new HashMap<String, String>();
			params.put("MapStageId", String.valueOf(stageId));
			ApiDto apiDto = ApiDto.buildPostContentApiDto(params);

			Map<String, ?> showMazeResult = httpApiService.showMaze(apiDto);
			System.out.println(showMazeResult);
			if (BigDecimal.ZERO.compareTo(BigDecimalUtil.convert(showMazeResult.get("Clear"))) != 0)
			{
				throw new MazeClearException();
			}
			BigDecimal layer = BigDecimalUtil.convert(showMazeResult.get("Layer"));
			if (isMazeStageFinish(stageId, layer))
			{
				layer = layer.add(BigDecimal.ONE);
			}
			for (int i = 0; i < 32; i++)
			{
				clearMazeLayer(stageId, layer, i);
			}
			clearMaze(stageId);
		}
		catch (HttpException e)
		{
			throw new SysException(e);
		}
		catch (IOException e)
		{
			throw new SysException(e);
		}
	}

	/**
	 * @param stageId
	 * @param showMazeResult
	 * @return
	 * @throws HttpException
	 * @throws IOException
	 */
	@SuppressWarnings("rawtypes")
	private boolean isMazeStageFinish(int stageId, BigDecimal layer) throws HttpException, IOException
	{
		Map<String, String> mazeInfoParams = new HashMap<String, String>();
		mazeInfoParams.put("MapStageId", String.valueOf(stageId));
		mazeInfoParams.put("Layer", String.valueOf(layer));
		ApiDto mazeInfoApiDto = ApiDto.buildPostContentApiDto(mazeInfoParams);
		Map<String, ?> mazeInfoResult = httpApiService.mazeInfo(mazeInfoApiDto);
		log.info("mazeInfo:" + mazeInfoResult);
		return (Boolean) ((Map) mazeInfoResult.get("Map")).get("IsFinish");
	}

	/**
	 * @param stageId
	 * @param layer
	 * @param i
	 * @throws HttpException
	 * @throws IOException
	 */
	private void clearMazeLayer(int stageId, BigDecimal layer, int itemIndex) throws HttpException, IOException
	{
		try
		{
			Map<String, String> battleParams = new HashMap<String, String>();
			battleParams.put("MapStageId", String.valueOf(stageId));
			battleParams.put("OpenCardChip", "1");
			battleParams.put("ItemIndex", String.valueOf(itemIndex));
			battleParams.put("manual", "0");
			battleParams.put("Layer", layer.toString());
			ApiDto battleApiDto = ApiDto.buildPostContentApiDto(battleParams);
			Map<String, ?> battleResult = httpApiService.mazeBattle(battleApiDto);
			System.out.println(battleResult);
		}
		catch (IllegalStateException e)
		{

		}
	}
}
